/**
 * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
 *
 * You may not modify, use, reproduce, or distribute this software except in
 * compliance with  the terms of the License at:
 * http://java.net/projects/javaeetutorial/pages/BerkeleyLicense
 */
package com.dmxtechnologies.community.rar.outbound;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;

import javax.resource.ResourceException;
import javax.resource.spi.ConnectionEvent;
import javax.resource.spi.ConnectionEventListener;
import javax.resource.spi.ConnectionRequestInfo;
import javax.resource.spi.LocalTransaction;
import javax.resource.spi.ManagedConnection;
import javax.resource.spi.ManagedConnectionMetaData;
import javax.security.auth.Subject;
import javax.transaction.xa.XAResource;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;

import com.dmxtechnologies.community.rar.api.CMSBaseRequest;

/* Represents a physical connection to the EIS.
 * The container maintains a pool of instances of this class */
public class CMSManagedConnection implements ManagedConnection {

    private static final Logger log = Logger.getLogger("CMSManagedConnection");
       
    private List<CMSConnectionImpl> createdConnections;
    private Socket socket;
    private PrintWriter logwriter;
    
    private String interfaceName;
    private String host;
    private Integer port;
    private String projectName;

	private ConnectionEventListener eventListener;
    
    public String getInterfaceName() {
		return interfaceName;
	}

	public void setInterfaceName(String interfaceName) {
		this.interfaceName = interfaceName;
	}

	public String getHost() {
		return host;
	}

	public void setHost(String host) {
		this.host = host;
	}

	public Integer getPort() {
		return port;
	}

	public void setPort(Integer port) {
		this.port = port;
	}

	public String getProjectName() {
		return projectName;
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	/* Called by the container from 
     * TradeManagedConnectionFactory.createManagedConnection
     * Creates a physical connection to the EIS */
    static int a = 0;
	public CMSManagedConnection(String host, Integer port,String projectName,String interfaceName) throws IOException {
        a++;
        log.info("[CMSManagedConnection] Constructor");
        createdConnections = new ArrayList<>();
        
        /* EIS-specific procedure to obtain a new connection */
        this.port = port;
        this.host = host;
        this.projectName = projectName;
        this.interfaceName = interfaceName;
        log.info("Connected!");
        System.out.println(a);
	}
    
    /* should return json format string */
    public String sendRequestToEIS(CMSBaseRequest request) throws IOException {
        return null;
    }
    
    /* should return json format string */
   	public String sendRequestToEIS(String url) {
   		Client client = ClientBuilder.newClient();
   		String name = null;
		try {
			name = client.target(url)
			.request(MediaType.APPLICATION_JSON_TYPE)
			.get(String.class);
		} catch (Exception e) {
			log.info(e.getMessage());
		}finally{
			client.close();
		}
   		return name;
   	} 
   	
    /* Called by the container to return a new connection handle. */
    @Override
    public Object getConnection(Subject subject, ConnectionRequestInfo cinfo) 
                                throws ResourceException {
        /* This example does not use security (Subject) */
        log.info("[CMSManagedConnection] getConnection()");
        return new CMSConnectionImpl(this);
    }

    /* Called by the container to destroy a physical connection. */
    @Override
    public void destroy() throws ResourceException {
        try {
            log.info("[CMSManagedConnection] destroy()");
            socket.close();
        } catch (IOException e) {}
        
    }

    /* Called by the container to clean up client-specific state. */
    @Override
    public void cleanup() throws ResourceException { 
        log.info("[CMSManagedConnection] cleanup()");
        for (CMSConnectionImpl con : createdConnections)
            if (con != null)
                con.invalidate();
    }

    /* Called by the container to associate a different connection handle */
    @Override
    public void associateConnection(Object connection) throws ResourceException {
        log.info("[CMSManagedConnection] associateConnection()");
        ((CMSConnectionImpl) connection).setManagedConnection(this);
    }
    
    public void disassociateConnection() {
        if (eventListener != null){
      	  eventListener.connectionClosed(new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED));
        }
    }

    @Override
    public void addConnectionEventListener(ConnectionEventListener listener) {
	    eventListener = listener;
    }

    @Override
    public void removeConnectionEventListener(ConnectionEventListener listener) {
	    eventListener = null;
    }

    @Override
    public XAResource getXAResource() throws ResourceException {
        return null;
    }

    
    
    @Override
    public LocalTransaction getLocalTransaction() throws ResourceException {
        return null;
    }

    @Override
    public ManagedConnectionMetaData getMetaData() throws ResourceException {
        return new ManagedConnectionMetaData() {
            @Override
            public String getEISProductName() throws ResourceException {
                return "DMX CMS SYSTEM";
            }
            @Override
            public String getEISProductVersion() throws ResourceException {
                return "unknown";
            }
            @Override
            public int getMaxConnections() throws ResourceException {
                return -1;
            }
            @Override
            public String getUserName() throws ResourceException {
                return "defaultUser";
            }
        };
    }

    @Override
    public void setLogWriter(PrintWriter out) throws ResourceException {
        this.logwriter = out;
    }

    @Override
    public PrintWriter getLogWriter() throws ResourceException {
        return logwriter;
    }
}
